﻿using log4net;
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Threading;
using System.Messaging;
using MSMQMessage = System.Messaging.Message;

namespace Klinkby.MicroBus
{    
    /// <summary>
    /// Queues a message in MSMQ until it can be successfully published to a WCF endpoint
    /// </summary>
    [Serializable]
    internal sealed class QueuedSender : Sender
    {
        readonly static ILog _log = LogManager.GetLogger(typeof(QueuedSender));
        readonly MuxerQueue _queue;

        private QueuedSender(string name)
            : base(name)
        {
            _log.Info(".ctor QueuedSender: " + name);
            _queue = new MuxerQueue(name, OnMessageAvailable);
        }

        public new static IAsyncFilter FromXml(XElement e, IAsyncFilter[] children)
        {
            Debug.Assert(children.Length == 0, "Sender shouldn't have children");
            Safe.NonNull(e, "e");
            Safe.Validate(e, () => "QueuedSender" == e.Name.LocalName, "Not a QueuedSender element");
            return new QueuedSender(e.AttributeValue("name"));
        }

        void OnMessageAvailable()
        {
            _log.Info("Message(s) available");
            while (_queue.Dequeue(base.Process))
                ;
        }

        public override void Process(IMessage message)
        {
            _log.Info("Enqueueing " + message.Topic);
            _queue.Enqueue(message);
        }

        //protected override void Dispose(bool disposing)
        //{
        //    try
        //    {
        //        if (disposing)
        //        {
        //            _queue.Dispose();
        //        }
        //    }
        //    finally
        //    {
        //        base.Dispose(disposing);
        //    }
        //}
    }    
}
